home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / programr / eckelt01.zip / 10 / BINARY.CPP < prev    next >
C/C++ Source or Header  |  1995-02-23  |  14KB  |  488 lines

  1. // File from page 406 in "Thinking in C++" by Bruce Eckel
  2. //////////////////////////////////////////////////
  3. // From the compressed package ECKELT01.ZIP 2/21/95
  4. // Copyright (c) Bruce Eckel, 1995 
  5. // Source code file from the book "Thinking in C++", 
  6. // Prentice Hall, 1995, ISBN: 0-13-917709-4
  7. // All rights reserved EXCEPT as allowed by the following 
  8. // statements: You may freely use this file for your own 
  9. // work, including modifications and distribution in 
  10. // executable form only. You may copy and distribute this 
  11. // file, as long as it is only distributed in the complete 
  12. // (compressed) package with the other files from this 
  13. // book and you do not remove this copyright and notice. 
  14. // You may not distribute modified versions of the source 
  15. // code in this package. This package may be freely placed 
  16. // on bulletin boards, internet nodes, shareware disks and 
  17. // product vendor disks. You may not use this file in 
  18. // printed media without the express permission of the 
  19. // author. Bruce Eckel makes no 
  20. // representation about the suitability of this software 
  21. // for any purpose. It is provided "as is" without express 
  22. // or implied warranty of any kind. The entire risk as to 
  23. // the quality and performance of the software is with 
  24. // you. Should the software prove defective, you assume 
  25. // the cost of all necessary servicing, repair, or 
  26. // correction. 
  27. // If you think you've found an error, please 
  28. // email all modified files with loudly commented changes 
  29. // to: eckel@aol.com (please use the same 
  30. // address for non-code errors found in the book).
  31. //////////////////////////////////////////////////
  32.  
  33. //: BINARY.CPP -- Overloading binary operators
  34. #include <fstream.h>
  35. #include "..\allege.h"
  36. ofstream out("binary.out");
  37.  
  38. class integer { // Combine this with UNARY.CPP
  39.   long i;
  40. public:
  41.   integer(long I = 0) : i(I) {}
  42.   // Operators that create new, modified value:
  43.   friend const integer
  44.     operator+(const integer& left,
  45.               const integer& right);
  46.   friend const integer
  47.     operator-(const integer& left,
  48.               const integer& right);
  49.   friend const integer
  50.     operator*(const integer& left,
  51.               const integer& right);
  52.   friend const integer
  53.     operator/(const integer& left,
  54.               const integer& right);
  55.   friend const integer
  56.     operator%(const integer& left,
  57.               const integer& right);
  58.   friend const integer
  59.     operator^(const integer& left,
  60.               const integer& right);
  61.   friend const integer
  62.     operator&(const integer& left,
  63.               const integer& right);
  64.   friend const integer
  65.     operator|(const integer& left,
  66.               const integer& right);
  67.   friend const integer
  68.     operator<<(const integer& left,
  69.                const integer& right);
  70.   friend const integer
  71.     operator>>(const integer& left,
  72.                const integer& right);
  73.   // Assignments modify & return lvalue:
  74.   friend integer&
  75.     operator+=(integer& left,
  76.                const integer& right);
  77.   friend integer&
  78.     operator-=(integer& left,
  79.                const integer& right);
  80.   friend integer&
  81.     operator*=(integer& left,
  82.                const integer& right);
  83.   friend integer&
  84.     operator/=(integer& left,
  85.                const integer& right);
  86.   friend integer&
  87.     operator%=(integer& left,
  88.                const integer& right);
  89.   friend integer&
  90.     operator^=(integer& left,
  91.                const integer& right);
  92.   friend integer&
  93.     operator&=(integer& left,
  94.                const integer& right);
  95.   friend integer&
  96.     operator|=(integer& left,
  97.                const integer& right);
  98.   friend integer&
  99.     operator>>=(integer& left,
  100.                 const integer& right);
  101.   friend integer&
  102.     operator<<=(integer& left,
  103.                 const integer& right);
  104.   // Conditional operators return true/false:
  105.   friend int
  106.     operator==(const integer& left,
  107.                const integer& right);
  108.   friend int
  109.     operator!=(const integer& left,
  110.                const integer& right);
  111.   friend int
  112.     operator<(const integer& left,
  113.               const integer& right);
  114.   friend int
  115.     operator>(const integer& left,
  116.               const integer& right);
  117.   friend int
  118.     operator<=(const integer& left,
  119.                const integer& right);
  120.   friend int
  121.     operator>=(const integer& left,
  122.                const integer& right);
  123.   friend int
  124.     operator&&(const integer& left,
  125.                const integer& right);
  126.   friend int
  127.     operator||(const integer& left,
  128.                const integer& right);
  129.   // Write the contents to an ostream:
  130.   void print(ostream& os) const { os << i; }
  131. };
  132.  
  133. const integer
  134.   operator+(const integer& left,
  135.             const integer& right) {
  136.   return integer(left.i + right.i);
  137. }
  138. const integer
  139.   operator-(const integer& left,
  140.             const integer& right) {
  141.   return integer(left.i - right.i);
  142. }
  143. const integer
  144.   operator*(const integer& left,
  145.             const integer& right) {
  146.   return integer(left.i * right.i);
  147. }
  148. const integer
  149.   operator/(const integer& left,
  150.             const integer& right) {
  151.   allege(right.i != 0, "divide by zero");
  152.   return integer(left.i / right.i);
  153. }
  154. const integer
  155.   operator%(const integer& left,
  156.             const integer& right) {
  157.   allege(right.i != 0, "modulo by zero");
  158.   return integer(left.i % right.i);
  159. }
  160. const integer
  161.   operator^(const integer& left,
  162.             const integer& right) {
  163.   return integer(left.i ^ right.i);
  164. }
  165. const integer
  166.   operator&(const integer& left,
  167.             const integer& right) {
  168.   return integer(left.i & right.i);
  169. }
  170. const integer
  171.   operator|(const integer& left,
  172.             const integer& right) {
  173.   return integer(left.i | right.i);
  174. }
  175. const integer
  176.   operator<<(const integer& left,
  177.              const integer& right) {
  178.   return integer(left.i << right.i);
  179. }
  180. const integer
  181.   operator>>(const integer& left,
  182.              const integer& right) {
  183.   return integer(left.i >> right.i);
  184. }
  185. // Assignments modify & return lvalue:
  186. integer& operator+=(integer& left,
  187.                     const integer& right) {
  188.    if(&left == &right) {/* self-assignment */}
  189.    left.i += right.i;
  190.    return left;
  191. }
  192. integer& operator-=(integer& left,
  193.                     const integer& right) {
  194.    if(&left == &right) {/* self-assignment */}
  195.    left.i -= right.i;
  196.    return left;
  197. }
  198. integer& operator*=(integer& left,
  199.                     const integer& right) {
  200.    if(&left == &right) {/* self-assignment */}
  201.    left.i *= right.i;
  202.    return left;
  203. }
  204. integer& operator/=(integer& left,
  205.                     const integer& right) {
  206.    allege(right.i != 0, "divide by zero");
  207.    if(&left == &right) {/* self-assignment */}
  208.    left.i /= right.i;
  209.    return left;
  210. }
  211. integer& operator%=(integer& left,
  212.                     const integer& right) {
  213.    allege(right.i != 0, "modulo by zero");
  214.    if(&left == &right) {/* self-assignment */}
  215.    left.i %= right.i;
  216.    return left;
  217. }
  218. integer& operator^=(integer& left,
  219.                     const integer& right) {
  220.    if(&left == &right) {/* self-assignment */}
  221.    left.i ^= right.i;
  222.    return left;
  223. }
  224. integer& operator&=(integer& left,
  225.                     const integer& right) {
  226.    if(&left == &right) {/* self-assignment */}
  227.    left.i &= right.i;
  228.    return left;
  229. }
  230. integer& operator|=(integer& left,
  231.                     const integer& right) {
  232.    if(&left == &right) {/* self-assignment */}
  233.    left.i |= right.i;
  234.    return left;
  235. }
  236. integer& operator>>=(integer& left,
  237.                      const integer& right) {
  238.    if(&left == &right) {/* self-assignment */}
  239.    left.i >>= right.i;
  240.    return left;
  241. }
  242. integer& operator<<=(integer& left,
  243.                      const integer& right) {
  244.    if(&left == &right) {/* self-assignment */}
  245.    left.i <<= right.i;
  246.    return left;
  247. }
  248. // Conditional operators return true/false:
  249. int operator==(const integer& left,
  250.                const integer& right) {
  251.     return left.i == right.i;
  252. }
  253. int operator!=(const integer& left,
  254.                const integer& right) {
  255.     return left.i != right.i;
  256. }
  257. int operator<(const integer& left,
  258.               const integer& right) {
  259.     return left.i < right.i;
  260. }
  261. int operator>(const integer& left,
  262.               const integer& right) {
  263.     return left.i > right.i;
  264. }
  265. int operator<=(const integer& left,
  266.                const integer& right) {
  267.     return left.i <= right.i;
  268. }
  269. int operator>=(const integer& left,
  270.                const integer& right) {
  271.     return left.i >= right.i;
  272. }
  273. int operator&&(const integer& left,
  274.                const integer& right) {
  275.     return left.i && right.i;
  276. }
  277. int operator||(const integer& left,
  278.                const integer& right) {
  279.     return left.i || right.i;
  280. }
  281.  
  282. void h(integer& c1, integer& c2) {
  283.   // A complex expression:
  284.   c1 += c1 * c2 + c2 % c1;
  285.   #define TRY(op) \
  286.   out << "c1 = "; c1.print(out); \
  287.   out << ", c2 = "; c2.print(out); \
  288.   out << ";  c1 " #op " c2 produces ";\
  289.   (c1 op c2).print(out); \
  290.   out << endl;
  291.   TRY(+) TRY(-) TRY(*) TRY(/)
  292.   TRY(%) TRY(^) TRY(&) TRY(|)
  293.   TRY(<<) TRY(>>) TRY(+=) TRY(-=)
  294.   TRY(*=) TRY(/=) TRY(%=) TRY(^=)
  295.   TRY(&=) TRY(|=) TRY(>>=) TRY(<<=)
  296.   // Conditionals:
  297.   #define TRYC(op) \
  298.   out << "c1 = "; c1.print(out); \
  299.   out << ", c2 = "; c2.print(out); \
  300.   out << ";  c1 " #op " c2 produces ";\
  301.   out << (c1 op c2); \
  302.   out << endl;
  303.   TRYC(<) TRYC(>) TRYC(==) TRYC(!=) TRYC(<=)
  304.   TRYC(>=) TRYC(&&) TRYC(||)
  305. }
  306.  
  307. // Member operators (implicit "this"):
  308. class byte { // Combine this with UNARY.CPP
  309.   unsigned char b;
  310. public:
  311.   byte(unsigned char B = 0) : b(B) {}
  312.   // No side effects: const member function:
  313.   const byte
  314.     operator+(const byte& right) const {
  315.     return byte(b + right.b);
  316.   }
  317.   const byte
  318.     operator-(const byte& right) const {
  319.     return byte(b - right.b);
  320.   }
  321.   const byte
  322.     operator*(const byte& right) const {
  323.     return byte(b * right.b);
  324.   }
  325.   const byte
  326.     operator/(const byte& right) const {
  327.     allege(right.b != 0, "divide by zero");
  328.     return byte(b / right.b);
  329.   }
  330.   const byte
  331.     operator%(const byte& right) const {
  332.     allege(right.b != 0, "modulo by zero");
  333.     return byte(b % right.b);
  334.   }
  335.   const byte
  336.     operator^(const byte& right) const {
  337.     return byte(b ^ right.b);
  338.   }
  339.   const byte
  340.     operator&(const byte& right) const {
  341.     return byte(b & right.b);
  342.   }
  343.   const byte
  344.     operator|(const byte& right) const {
  345.     return byte(b | right.b);
  346.   }
  347.   const byte
  348.     operator<<(const byte& right) const {
  349.     return byte(b << right.b);
  350.   }
  351.   const byte
  352.     operator>>(const byte& right) const {
  353.     return byte(b >> right.b);
  354.   }
  355.   // Assignments modify & return lvalue.
  356.   // operator= can only be a member function:
  357.   byte& operator=(const byte& right) {
  358.     // Handle self-assignment:
  359.     if(this == &right) return *this;
  360.     b = right.b;
  361.     return *this;
  362.   }
  363.   byte& operator+=(const byte& right) {
  364.     if(this == &right) {/* self-assignment */}
  365.     b += right.b;
  366.     return *this;
  367.   }
  368.   byte& operator-=(const byte& right) {
  369.     if(this == &right) {/* self-assignment */}
  370.     b -= right.b;
  371.     return *this;
  372.   }
  373.   byte& operator*=(const byte& right) {
  374.     if(this == &right) {/* self-assignment */}
  375.     b *= right.b;
  376.     return *this;
  377.   }
  378.   byte& operator/=(const byte& right) {
  379.     allege(right.b != 0, "divide by zero");
  380.     if(this == &right) {/* self-assignment */}
  381.     b /= right.b;
  382.     return *this;
  383.   }
  384.   byte& operator%=(const byte& right) {
  385.     allege(right.b != 0, "modulo by zero");
  386.     if(this == &right) {/* self-assignment */}
  387.     b %= right.b;
  388.     return *this;
  389.   }
  390.   byte& operator^=(const byte& right) {
  391.     if(this == &right) {/* self-assignment */}
  392.     b ^= right.b;
  393.     return *this;
  394.   }
  395.   byte& operator&=(const byte& right) {
  396.     if(this == &right) {/* self-assignment */}
  397.     b &= right.b;
  398.     return *this;
  399.   }
  400.   byte& operator|=(const byte& right) {
  401.     if(this == &right) {/* self-assignment */}
  402.     b |= right.b;
  403.     return *this;
  404.   }
  405.   byte& operator>>=(const byte& right) {
  406.     if(this == &right) {/* self-assignment */}
  407.     b >>= right.b;
  408.     return *this;
  409.   }
  410.   byte& operator<<=(const byte& right) {
  411.     if(this == &right) {/* self-assignment */}
  412.     b <<= right.b;
  413.     return *this;
  414.   }
  415.   // Conditional operators return true/false:
  416.   int operator==(const byte& right) const {
  417.       return b == right.b;
  418.   }
  419.   int operator!=(const byte& right) const {
  420.       return b != right.b;
  421.   }
  422.   int operator<(const byte& right) const {
  423.       return b < right.b;
  424.   }
  425.   int operator>(const byte& right) const {
  426.       return b > right.b;
  427.   }
  428.   int operator<=(const byte& right) const {
  429.       return b <= right.b;
  430.   }
  431.   int operator>=(const byte& right) const {
  432.       return b >= right.b;
  433.   }
  434.   int operator&&(const byte& right) const {
  435.       return b && right.b;
  436.   }
  437.   int operator||(const byte& right) const {
  438.       return b || right.b;
  439.   }
  440.   // Write the contents to an ostream:
  441.   void print(ostream& os) const {
  442.     os << "0x" << hex << int(b) << dec;
  443.   }
  444. };
  445.  
  446. void k(byte& b1, byte& b2) {
  447.   b1 = b1 * b2 + b2 % b1;
  448.  
  449.   #define TRY2(op) \
  450.   out << "b1 = "; b1.print(out); \
  451.   out << ", b2 = "; b2.print(out); \
  452.   out << ";  b1 " #op " b2 produces ";\
  453.   (b1 op b2).print(out); \
  454.   out << endl;
  455.  
  456.   b1 = 9; b2 = 47;
  457.   TRY2(+) TRY2(-) TRY2(*) TRY2(/)
  458.   TRY2(%) TRY2(^) TRY2(&) TRY2(|)
  459.   TRY2(<<) TRY2(>>) TRY2(+=) TRY2(-=)
  460.   TRY2(*=) TRY2(/=) TRY2(%=) TRY2(^=)
  461.   TRY2(&=) TRY2(|=) TRY2(>>=) TRY2(<<=)
  462.   TRY2(=) // Assignment operator
  463.  
  464.   // Conditionals:
  465.   #define TRYC2(op) \
  466.   out << "b1 = "; b1.print(out); \
  467.   out << ", b2 = "; b2.print(out); \
  468.   out << ";  b1 " #op " b2 produces ";\
  469.   out << (b1 op b2); \
  470.   out << endl;
  471.  
  472.   b1 = 9; b2 = 47;
  473.   TRYC2(<) TRYC2(>) TRYC2(==) TRYC2(!=) TRYC2(<=)
  474.   TRYC2(>=) TRYC2(&&) TRYC2(||)
  475.  
  476.   // Chained assignment:
  477.   byte b3 = 92;
  478.   b1 = b2 = b3;
  479. }
  480.  
  481. main() {
  482.   integer c1(47), c2(9);
  483.   h(c1, c2);
  484.   out << "\n member functions:" << endl;
  485.   byte b1(47), b2(9);
  486.   k(b1, b2);
  487. }
  488.